 

  #include <cstdio>
  #include <iostream>
  #include <fstream>
  #include <cstdlib>
  #include <cstring>
  #include <cfloat>
  #include <ctime>
//  #include <ctype.h>
  #include <cmath>
  #include <string>
  #include <limits>
  
  
  #include "evolimits.h"
  #include "mylib.h"
   


  using namespace std;

  #define DEFAULT_EVO_FILE   "evo-params.txt"
  /* E' il nome del file di default che viene letto per estrarre i paramet-
     ri evolutivi. 
  */
  #define DEFAULT_FIT_FILE   "fitness.txt"
  /* E' il nome del file di default che viene letto per estrarre i parame-
     tri della fitness.
  */
  #define NULL_INDIVIDUAL  (Individual *) 0
  /* Rappresenta il valore nullo per i puntatori agli oggetti della
     classe Individual.
  */


  enum problem_types {null_prob, min_, max_};
  /* Questo tipo enumerativo viene utilizzato per denotare i due tipi di
     problemi possibili: minimizzazione (min) o massimizzazione (max). Il 
     primo elemento rappresento l'elemento nullo. 
  */
  enum target_type {null_target, super, pop, subs};
  /* Questo tipo enumerativo denota il tipo di risultato che si vuole ottte-
     nere: un super individuo (super), una popolazione (pop), un insieme di
     sottopopolazioni (subs). Anche in questo caso il primo e' l'elemento 
     nullo.
  */
  enum evo_type {null_evo, gen, steady, gp};
  /* Questo tipo enumerativo denota il tipo di evoluzione che si vuole rea-
     lizzare: steady, generazionale. Anche in questo caso il primo e' l'elemento 
     nullo.
  */
  enum choose_type {null_sel, rand_, wheel, tournment, stoc_uni, trunc_};
  /* Questo tipo enumerativo viene utilizzato per denotare il tipo di
     scelta da usare nella scelta di un individuo della  popolazione:
     rand, wheel (roulette wheel),il tournment oppure Stochastic Uni-
     versal Sampling (stoc_uni).
  */

 /******************************************************************
  *****  Definizione della struttura per la memorizzzione del  *****
  *****  andamento di un run.                                  ***** 
  ******************************************************************/
  struct variable 
  {
        double best_val, ave_val, dev_val, min_val, max_val;        
  };
  /* Questa struttura memorizza il valore del migliore individuo, quello 
     medio e la deviazione standard di un certa variabile. E anche il 
     valore massimo e quello minimo.
  */   
  
  /*******************************************************************
  ******************  Definizioni legate alla fitness   **************
  *******************************************************************/


  #define NULL_FITNESS  0.0
  /* Rappresenta il valore nullo della fitness. */
  #define MAX_FITNESS   1000000.0
  /* Rappresenta il valore massimo della fitness. */


  /************************************************************************

   Definizione delle classi: POPULATION, INDIVIDUAL, EVOLUTION, 
                             CROSSOVER, MUTATION.

  ************************************************************************/


  class Individual;
  class Crossover;
  class Mutation;
  class Fitness;
  class Evolution;
  /* Dichiarazione delle classi utilizzate successivamente nel file.
  */

  /*
  ++++++++++++++++++++++++ Classe POPULATION ++++++++++++++++++++++++
  *** Definita il: 
  Contiene il riferimento agli individui della popolazione, imple-
  mentato attraverso un array di puntatori (l'array chiamato
  individuals)agli oggetti della classe Individual. Ogni individuo
  � indirizzato attraverso un intero che rapresenta l'indice
  nell'array suddetto.
  *** Ultima modifica: ore 17.00 del 04/04/03
  */

  class Population
  {
  public:
      
     Population();
     /* E' la costruttrice della classe. E' vuota. 
     */
     Population(int N, Evolution *evo_ptr);
     /* E' una seconda costruttrice della classe. Il parametro N specifica
        il numero di individui che la popolazione dovra' contenere.  Il se-
        condo parametro specifica il puntatore alla classe Evolution che ha
        generato la popolazione.
     */
     virtual void breed() {};
     /* E' la procedura che genera gli individui specifici delle classe de-
        rivate. 
     */ 
     double average_fit;
     /* E' la fitness media della popolazione.
     */     
     Population *build_copy();
     /* Costruisce una copia della popolazione e ne restituisce il puntatore.
     */
     Individual *best;
     /* E' un puntatore  al miglior individuo della popolazione.
     */
     virtual void show_data(ostream *out_stream);
     /* Mostra i suoi dati sull'output passato come parametro.
     */
     void get_evo_ptr(Evolution *evo_ptr);
     /* Acquisisce il puntatore alla passato come parametro che � il memo
        rizzato come puntatore alla classe Evolution.
     */
     void comp_score(int ind_index, problem_types type);
     /*Calcola lo score dell'individuo passato come parametro. il secondo
       paramatro specifica se un problema di max o min.
     */  
     virtual void comp_fitnesses();
     /* Calcola le fitness degli individui della popolazione.
     */
  protected: 
     int ind_counter;
     /* E' il numero di individui attualmente presente nella popolazione.
     */
     int N_inds;
     /* E' il numero di individui che deve contenere la popolazione.
     */
     Individual *individuals[MAX_INDIVIDUALS];
     /* E' l'array di puntatori agli individui della classe.
     */
     Evolution *evolution;
     /* E' il puntatore all'oggetto della classe Evolution che contiene del-
        le informazioni che devono essere utilizzate anche dagli oggetti
        della classe Population.
     */
     double tot_fitness;
     /* E' la fitness totale della popolazione, cio� la somma delle
        fitness di ogni singolo individuo.
     */
     double  tot_fitness_inv;
     /* E' la variabile che memorizza la somma delle inverse delle fitness,
        e serve per la roulette wheel per problemi di minimizzazione.
     */
     Individual *stoc_uni_individuals[MAX_INDIVIDUALS];
     /* E' l'array utilizzato per implementare la Stochastic Universal Sam-
        pling.
     */    
     virtual void update();
     /* Aggiorna gli attribuiti di tutti gli individui popolazione dopo
        l'applicazione degli operatori.
     */     
     void kill();
     /* Distrugge gli individui della popolazione che non sono stati copiati
        nella nuova popolazione.
     */
     void comp_data();
     /* Effettua alcuni relativi alla popolazione, come fitness media, to-
        tale, ecc.
     */
     void comp_vars(int vars_num, struct variable vars_vec[]);
     /* Calcola i valori delle variabili di cui tenere conto. I primo para-
        metro  rappresenta il numero du queste variabili, il secondo l'ar-
        ray in cui memorizzarle. 
     */
     Individual *find_best(problem_types type);
     /* Trova il miglior individuo della popolazione. Il parametro type in-
        dica se si tratta di un problema di minimizzazione o di massimizza-
        zione.
     */
     Individual *select(choose_type choose, problem_types type);
     /* Seleziona un individuo della popolazione in maniera casuale, usando
        il tipo di distribuzione specificato come input. Type specifica se
        si tratta di un problema di minimizzazione o massimizzazione.
     */
     void add_individual(Individual *individual);
     /* Aggiunge un nuovo individuo alla popolazione, puntandolo con
        un elemento dell'array di puntatori.
     */
     void build_sus_array(problem_types type);
     /* E' la procedura che implementa l'algoritmo SUS. Il parametro type 
        specifica il tipo di problema.
     */
     void QSort(int left, int right, problem_types type);
     /* E' l'algoritmo quick sort per l'ordinamento degli individui della
        popolazione. Il parametro type specifica se si tratta di problemi
        di massimizzazione o di minimizzazione.
     */
     void QSort(int left, int right);
     /* E' l'algoritmo quick sort per l'ordinamento degli individui della
        popolazione in base allo score.
     */
     virtual void improve();
     /* Questa procedura e' virtuale e deve essere definita all'interno
        delle classi derivate. Il suo ruolo e' quello di contenere delle
        procedure, specifiche del problema da affrontare, che siano in gra-
        do di migliorare gli individui della popolazione corrente. In pra-
        tica questa procedura puo' essere utile anche per ibridizzare l'al-
        goritmo.
     */

   friend class Evolution;
   friend class Experiment;   
   };

  /*
  +++++++++++++++++++++++++++ classe INDIVIDUAL +++++++++++++++++++++++++++
  *** Definita il: 
  Gli oggetti di questa classe sono i singoli individui della popolazione e
  sono degli alberi di generazione di espressioni ottenuti applicando le
  regole della grammatica.
  *** Ultima modifica: ore 17.00 del 04/04/03
  */
  class Individual
  {
  public:

    Individual();
    /* E' la costruttrice della classe. Pone l'attributo alive pari a
        TRUE.
     */
    Individual(Evolution *evo_ptr);
    /* E' la seconda costruttrice della classe. Le viene passato il punta-
       tore alla classe evolution che l'ha generato e pone l'attributo 
       alive pari a TRUE.  */
     bool alive;
     /* Questo attributo indica se l'indiviuo e ancora vivo oppure se e' 
        stato ucciso. 
     */
     double give_fitness();//{return fitness;};
     /* Resituisce la fitness dell'individuo.
     */
     int give_score(){ return score;};
     /* Restituisce lo score dell'individuo.
     */
     double give_var(int index){return inner_vars[index];};
     /* Restituisce il valore della variabile built-in di indice index.
     */
     virtual double comp_fitness() = 0;
     /* Calcola e restituisce la fitness dell'individuo. E' una funzione
        virtuale PURA.
     */
     virtual double comp_fitness(double (*fit_funct)(Individual *)){return 0.0;};
     /* Anche questa funzione calcola la fitness dell'individuo, con una 
        differenza molto importante: le viene passata una funzione che che 
	effettua il calcolo della fitness dell'individuo. Tipicamente, ques-
	ta funzione e' la eval della classe Fitness. E' una funzione virtua-
	le.
     */
     virtual void update();
     /* Aggiorna  tutti gli attribuiti, dopo che l'individuo e' stato modi-
        ficato dagli aperatori genetici, chiamando le funzioni che effet-
        tuano i relativi calcoli.
     */
     virtual Individual *build_copy() = 0;
     /* Questa procedura costruisce una copia dell'individuo e restituisce 
        il puntatore all'individuo copia. E' una funzione virtuale PURA!!!.
        Quindi deve essere definita all'interno delle classi derivate. 
     */
     virtual void show(ostream *out_stream);      
     /* Mostra nell'output passato come parametro le variabili built-in, 
        utilizzate dall'individuo. 
     */     
     virtual void kill() = 0;
     /* Elimina l'individuo, tipicamente serve a restituire alla memoria le 
        strutture dati utilizzate. 
     */
     void virtual comp_data(){return;};
     /* E'un procedura per ulteriori calcoli, che solitamente vengono fatti
        solo sul migliore individuo.*/
     double comp_time();
     /* Calcola il valore di time.
     */ 
     void set_score(int s_val){score = s_val;}
     
     void get_evo_ptr(Evolution *e){evo_ptr = e;}
     
    
  protected:
      
     double fitness;
     /*  E' la fitness associata all'individuo.    
     */
     double time;
     /* E' il tempo trascorso per generare l'individuo dall'inizio del run.
     */ 
     int score;
     /* E' lo score dell individuo.
     */
     Evolution *evo_ptr;
     /* E' il puntatore all'oggetto della classe Evolution che l'ha generato 
     */
     double inner_vars[MAX_VARS];
     /* Contiene l'informazione relativa all'individuo sulle variabili da 
        tenere sotto controllo.
     */     
     virtual void write_pheno() = 0;
     /* Scrive nel stringa phenotype la stringa corrispondente all'individuo.
     */ 
     
         

     friend class Population;     
     friend class Crossover;
     friend class Mutation;
     friend ostream &operator<<(ostream &stream, Individual &ind);
  };

  /*
  +++++++++++++++++++++++++++ classe  EVOLUTION ++++++++++++++++++++++++++++
  *** Definita il: 
  E' il vero "cuore" di tutto il programma, sono gli oggetti di questa
  classe, infatti, che contengono le informazioni sul numero di iterazioni
  da eseguire, sulle percentuali di applicazione dei vari operatori, sul
  tipo di distribuzione da applicare per ognuno degli operatori ecc.
  *** Ultima modifica: ore 17.00 del 04/04/03
  */

  class Evolution
  {
  public:
     Evolution ();
     /* E' la procedura costruttrice della classe, legge da file i valori
        da assegnare agli attributi  che specificano le modalit� di appli-
        cazione dei vari operatori.
     */
     virtual void start(int argc, char *argv[]) = 0;
     /* E' una funzione virtuale pura, essa deve essere definita all'inter-
        no delle varie classi derivate. La sua funzione deve essere quella 
        di leggere i diversi file necessari all'esecuzione dell'algoritmo e
        genera la popolazione iniziale. I due parametri passati servono al-
        la lettura della riga di comando.
     */
     virtual void init_run(int argc, char *argv[]) {return;}
     /* Serve a inizializzare stutture che vanno inizializzate prima di ogni 
      * run. Viene usata principalmente per experimenti ripetuti. 
     */      
     virtual void show_iter(ostream *out_stream);
     /* Mostra i risultati dell'iterazione appena eseguita sull'output pas-
        sato come parametro.
     */ 
     virtual void find_super(bool visual_mode);
     /* Esegue l'intero algoritmo alla ricerca di un super individuo, ese-
        guendo la procedura build_next_pop fino a quando non si raggiunge 
	    uno dei criteri di terminazione. Il parametro visual_mode indica se
	    stampare a video i risultati parziali ottenuti oppure no e gli even-
	    tuali messaggi.
     */
     void find_pop(bool visual_mode);
     /* E' uguale alla precedente, ma con una differenza molto importante 
        cerca un'intera popolazione e non un singolo super individuo. 
     */
     void find_subs(bool visual_mode);
     /* E' uguale alle precedenti solo che questa cerca delle sottopopola-
        zioni. 
     */
     Individual *best_so_far;
     /* E' il miglior individuo trovato fino a questo momento.
     */
     int N_inds;
     /* E' il numero di individui che bisogna generare per formare una po-
        polazione.
     */
     problem_types problem_type;
     /* Spedifica il tipo di problema: di minimizzazione o di massimizza-
        zione.
     */
     int N_iters;
     /* E' il numero massimo di evoluzioni dell'algoritmo. Ogni evoluzione
        applica gli operatori alla popolazione "corrente" e la trasforma in
        una nuova popolazione.
     */     
     int give_best_iter(){return best_iter; };
     /* Restituisce l'iterazione a cui e' stata trovata l'ultima  best so 
        far solution.
     */
     int give_tourn_size(){ return tourn_size;};
     /* Restituisce il numero di individui per il tournament.
     */
     int give_iters_done(){return iters_done;};
     /* Restituisce il numero di iterazioni effettuate al momento della sua
        chiamata. 
     */
     int give_iters_num(){return N_iters;};
     /* Restituisce il numero di iterazioni da effettuare. 
     */
     double give_trunc_size(){return trunc_size;};
     /* Restiuisce la percentuale di truncation.
     */
     
    
     //+++++++ Dati che possono essere utilizzati a fini STATISTICI. ++++++

     double avefit_story[MAX_ITERS];
     /* Questo vettore memorizza la fitness media della popolazione ottenu-
        ta ad ogni iterazione.
     */
     double bestfit_story[MAX_ITERS];
     /* Questo vettore memorizza la fitness del migliore individuo ottenuto
        ad ogni iterazione. 
     */
     struct variable vars_story[MAX_ITERS][MAX_VARS];
     /* Memorizza l'andamento delle variabili di cui bisogna tenere conto, 
        durante tutta l'evoluzione.
     */
     virtual void get_params(int argc, char *argv[]);
     /* Legge da file i parametri dell'evoluzione da implementare  e li as-
        segna agli attributi della classe. Alla procedura viene passata la 
        riga di comando. La procedura verifica in questo modo se aprire il 
        file di default oppure uno passato dall'utente.
     */
     Fitness *fitness;
     /* E' il puntatore all'oggetto della classe Fitness.
     */
     void give_params(ofstream *out_stream);
     /* Scrive tutti i parametri dell'evoluzione nel file passato come para-
        metro. 
     */
     virtual void give_more_params(ofstream *out_stream) {return;}
     /* Serve a restituire eventuali altri parametri specifici.
     */
     clock_t give_ini_time(){return ini_time;};

     float give_cross_prob() {return cross_prob;}
     float give_mut_prob()   {return mut_prob;}
     
  protected:
     target_type target;
     /* E' il tipo di obiettivo che si vuole ottenenere: superindividuo, po-
        polazione o sottoppolazioni.
     */
     evo_type e_type;
     /* E' il tipo di evoluzione da eseguire.
     */
     Population *curr_pop;
     /* E' il puntatore all'oggetto popolazione che deve essere trasformato
        applicando gli operatori evolutivi.
     */
     Population *next_pop;
     /* E' il puntatore all'oggetto popolazione che viene generato appli-
        cando gli operatori evolutivi all'oggetto popolazione puntato da
        curr_popolutation.
     */
     Population * tmp_pop;
     /* E' una popolazione temporanea e serve per gli algoritmi steady 
        state. 
     */
     int iters_done;
     /* E' il numero di evoluzioni (o meglio di iterazioni) dell'algoritmo
        gia' effettuate.
     */
     int best_iter;
     /* E' l'iterazione a cui e' stata trovata l'ultima  best so far solu-
        tion.
     */
     int elitism;
     /* E' il numero di migliori individui della popolazione corrente da 
        copiare nella popolazione successiva. Questo presuppone che la po-
        popolazione corrente sia ordinata.
     */
     float cross_prob;
     /* E' la probabilita' di applicazione dell'operatore Crossover.
     */
     float mut_prob;
     /* E' la probabilita' di applicazione dell'operatore Mutation.
     */
     double mut_range;
     /* E' il range della mutazione.
     */
     int tourn_size;
     /* E' il numero di individui che deve essere scelto per effettuare il
        tournment.
     */
     double trunc_size;
     /* E' la pecentuale di truncation.
     */
     int sus_num;
     /* E' il nuemero di elementi della popolazione da usare per lo
        STOCHASTIC UNIVERSAL SAMPLING.
     */
     Crossover *crossover;
     /* E' il puntatore all'oggetto della classe Crossover.
     */
     Mutation *mutation;
     /* E' il puntatore all'oggetto della classe Mutation.
     */
     bool stoc_choose;
     /* Questa variabile segnala se bisogna utilizzare, almeno per uno de-
        gli operatori, il SUS, in tal caso, si effettuano tutti i calcoli
        necessari.
     */
     choose_type selection;
     /* Rappresenta il tipo di selezione.
     */     
     virtual bool termination();
     /* Controlla se e' soddisfatto il criterio di terminazione dell'algo-
        ritmo.
     */
     bool visual;
     /* Specifica se visualiizare i risultati intermedi e gli eventuali
        messaggi agli utenti. */
     bool new_best_so_far;
     /* Registra eventuali miglioramenti della soluzioni best so far.
     */      
     virtual void check_params();
     /* Verifica se i parametri dell'evoluzione sono corretti.
     */
     bool extract_param(char *line);
     /* Estrae dalla linea in input il parametro contenuto e lo assegna
        al relativo attributo.
     */
     virtual bool extract_more_param(char *line){return false;}
     /* E' una procedura per estrarre parametri specifici delle particolari
        implementazioni, tipo GA, Multi, ecc.
     */
     choose_type get_select_type(char *string);
     /* Legge dalla stringa in input il tipo di selezione che contiene e lo
        restituisce.
     */
     virtual void build_next_pop();
     /* Costruisce la poplazione successiva partendo da quella corrente.
     */
     virtual void build_next_pop2();
     /* Costruisce la poplazione successiva partendo da quella corrente.
     */ 
     virtual void build_steady_pop();
     /* Costruisce la  prossima popolazioen con steady state.
     */
     virtual void memo_data_iter();
     /* Memorizza in array dedicati i dati relativi a tutte le iterazioni.
     */     
     int print_dist;
     /* E' la distanza tra la stampa dei risultati a terminale.
     */
     char file_name[MAX_CHAR_FILE_NAME];
     /* E' la stringa che contiene il nome del file dei parametri. 
     */
     ofstream run_stream, run_stream2;
     /* E' lo stream collegato al file di default nel quale memorizzare 
        i dati del run che vengono memorizzati anche a terminale.
     */
     clock_t ini_time;
     /* E' il momento di inizio del run.
     */

  friend class Population;
  friend class Experiment;
  };




  /*
  +++++++++++++++++++++++++++ classe CROSSOVER ++++++++++++++++++++++++++++
  *** Definita il: 
  Questa classe definisce l'operatore di crossover degli individui dalla
  popolazione corrente alla poplazione successiva. E' una classe ASTRATTA.
  *** Ultima modifica:
  */

  class Crossover
  {
  public:
     Crossover();
     /* E' la procedura costruttrice della classe (� vuota).
     */
     virtual void apply(Individual *input_ptr_1, Individual *input_ptr_2,
                Individual* &output_ptr_1, Individual* &output_ptr_2) = 0;
     /* Applica l'operazione di crossover alla coppia di individui in
        ingresso (input_ptr_1 e input_ptr_2), creandone due copie
        e applicandovi l'operazione di crossover. Le due copie cos�
        modificate vengono restituite nella seconda coppia di para-
        metri in ingresso (output_ptr_1 e output_ptr_2).
     */
     
     void give_cut(int len1, int len2, int &cut1, int &cut2, int delta);
     /* Calcola i punti di taglio t1 e t2 di due individui (di qualsiasi 
        tipo, ma con lunghezza variabile) che hanno lunghezza len1 e len2;
        Il parametro delta, specifica di quanto puo' spostarsi la lunghezza
        dei figli rispetto a quella dei genitori. 
     */
     
  protected: 
     float prob;
     /* E' la probabilita' di applicazione dell'operatore.*/   
  };


  /*
  +++++++++++++++++++++++++++ Classe MUTATION +++++++++++++++++++++++++++++
  *** Definita il: 
  Questa classe definisce l'operatore di mutazione degli individui dalla
  popolazione corrente alla poplazione successiva. E' una classe ASTRATTA.
  *** Ultima modifica: ore 17.00 del 04/04/03
  */
  class Mutation
  {
  public:
     Mutation();
     /*E' la procedura costruttrice della classe (� vuota).
     */
     void apply(Individual *input_ptr, Individual* &output_ptr);
     /* Applica l'operazione di mutazione all'individuo puntato dal primo
        parametro in ingresso (input_ptr), creandone una copia e applicando-
	vi l'operazione di mutazione. La copia cos� modificata viene resti-
	tuita nel secondo parametro (output_ptr).
     */
     void apply(Individual* input_ptr);
     /* E' uguale alla precedente tranne che per il fatto che non costruisce
        la copia ma modifica direttamente l'individuo passato come parametro.
     */
     virtual void mutate (Individual* input_ptr) = 0;
     /* E' la procedura che applica la mutazione. è virtuale pura: deve essere definita
        nelle sottclassi.
     */
  protected:
     float prob;
     /* E' la probabilita' di applicazione dell'operatore.
     */
     float range;
     /* E' il range dell'operatore.
     */   
  };
  


  /*
  +++++++++++++++++++++++++++ classe FITNESS ++++++++++++++++++++++++++++++
  *** Definita il: 22/12/03
  Questa classe e' utilizzata per calcolare la firnes dell'individuo.

  *** Ultima modifica:
  */
  class Fitness
  {
  public:
     Fitness ();
     /* E' la costruttrice della classe, e' vuota.
     */ 
     Fitness(bool visual);
     /* E' la seconda costruttrice della classe. Il parametro visual speci-
       fica se visualizzare il messaggio di corretta acquisizione.
     */
   //  virtual double eval(Individual *ind_ptr) = 0;
     /* Calcola la fitness dell'individuo passato come parametro.
     */
     double give_weight(int pos){return weights[pos];}
     /* Restituisce il valore del peso pos-esimo. 
     */
     double min;
     /* E' il valore minimo che puo' assumere la fitness di un individuo.
     */
     virtual void get_params(int argc, char *argv[]);
     /* Estrae da  file i parametri necessari al calcolo della fitness. I
        parametri passati servono per la lettura della riga di comando. 
     */
     void give_params(ofstream *out_stram);
     /* Copia nel file passato come parametro i parametri della fitness.
     */      
     virtual void show(ostream *out_stream){return;};
     /* Questa procedura serve a visualizzare informazioni relative allo 
        specifico problema da risolvere e per questo e' virtuale.
     */
     
     
  protected:
     bool visual;
     /* Specifica se stampare il messaggo di corretta acquisizione.
     */     
     virtual bool extract_param(char *line);
     /* Estrae dalla linea di caratteri passata come parametro uno dei parame-
        tri della funzione di fitness. */  
     char file_name[MAX_CHAR_FILE_NAME];
     /* Contiene il nome del file che contiene i parametri della fitness.
     */
     double weights[MAX_WEIGHTS];
     /* Contiene i pesi dei vari elementi della fitness.
     */
     friend class Experiment;
  };


  /*
  +++++++++++++++++++++++++++ classe VARIABLES ++++++++++++++++++++++++++++
  *** Definita il: 22/12/03
  Questa classe e' contiene tutte le informazioni sulle variabili buil-in 
  del sistema. In particolar modo contiene tutte le informazioni sui nomi 
  loro assegnati e il numero di quelle effettivamente utilizzate. 
  *** Ultima modifica:
  */
  class Variables
  {
  public:
    Variables();
    /* E'  la costruttrice della classe. E' vuota. 
    */   
    void get_names(bool visual);
    /* Carica dal file "names.txt" i nomi da associare alla variabili e il
       loro numero. Il parametro visual specifica se visualizzare un mes-
       saggio di acquisizione. 
    */
    int give_Num();
    /* Restituisce il numero di variabili built-in utilizzate.
    */
    string give_full(int index);
    /* Restituisce la stringa ceh contiene il nome completo della variabile 
       di indice index.
    */
    string give_short(int index);
    /* Restituisce la stringa che contiene il nome abbreviato della varia-
       bile di indice index.
    */
    void show_legend(ofstream *out_stream);
    /* Scrive nello stream passato come parametro la corrispondenza tra va-
       riabili abbreviate e complete. 
    */
    bool show_max_min(int index){return max_min[index];};
    /* Restituisce lo stato della variabile max_min di indice index, la qu-
       ale contiene l'informazione relativa alla visualizzazione dei valori
       massimi e minimi. 
    */
  private: 
  string fulls[MAX_VARS];
  /* Quest'array contiene  i nomi completi associati alle variabili built-
     in.
  */
  string shorts[MAX_VARS];
  /* Quest'array contiene  i nomi abbreviati associati alle variabili built-
     in.
  */ 
  void comp_shorts();
  /* Calcola le abbreviazioni dei nomi delle variabili.
  */
  void comp_short(int index);
  /* Calcola l' abbreviazione della variabile di indice index.
  */
  int Num;
  /* E' il numero di variabili built-in utilizzato. 
  */
  bool max_min[MAX_VARS];
  /* In questo vettore viene memorizzata l'informazione relativa alla visu-
     alizzazione dei valori massimi e minimi. */
      
  };  
